From 8411f1a2791adf5c75c83941dbaaa9d7189c6fa8 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 24 Nov 2011 21:00:57 +0100 Subject: [PATCH] Implement background-clip and background-origin --- gtk/gtkstyleproperty.c | 12 ++++++ gtk/gtkthemingengine.c | 88 +++++++++++++++++++++++++++++++++--------- 2 files changed, 81 insertions(+), 19 deletions(-) diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c index 21b190efa5..d300fefbca 100644 --- a/gtk/gtkstyleproperty.c +++ b/gtk/gtkstyleproperty.c @@ -2945,6 +2945,18 @@ gtk_style_property_init (void) "Border style", GTK_TYPE_BORDER_STYLE, GTK_BORDER_STYLE_NONE, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_enum ("background-clip", + "Background clip", + "Background clip", + GTK_TYPE_CSS_AREA, + GTK_CSS_AREA_BORDER_BOX, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_enum ("background-origin", + "Background origin", + "Background origin", + GTK_TYPE_CSS_AREA, + GTK_CSS_AREA_PADDING_BOX, 0)); _gtk_style_property_register (g_param_spec_boxed ("border-top-color", "Border top color", "Border top color", diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c index fabd30b4b6..0d30b97692 100644 --- a/gtk/gtkthemingengine.c +++ b/gtk/gtkthemingengine.c @@ -1446,17 +1446,55 @@ render_background_internal (GtkThemingEngine *engine, GtkStateFlags flags; gboolean running; gdouble progress; - GtkRoundedBox border_box; + GtkRoundedBox padding_box; + GtkRoundedBox clip_box; GtkShadow *box_shadow; - GtkBorder border; + GtkBorder border, padding; GtkStylePropertyContext context; + GtkCssArea clip, origin; + gdouble bg_width, bg_height, bg_x, bg_y; flags = gtk_theming_engine_get_state (engine); gtk_theming_engine_get_background_color (engine, flags, &bg_color); - context.width = width; - context.height = height; + gtk_theming_engine_get (engine, flags, + "background-origin", &origin, + "background-clip", &clip, + "background-repeat", &repeat, + "box-shadow", &box_shadow, + NULL); + + gtk_theming_engine_get_border (engine, flags, &border); + gtk_theming_engine_get_padding (engine, flags, &padding); + + /* The default size of the background image depends on the + background-origin value as this affects the top left + and the bottom right corners. */ + switch (origin) { + case GTK_CSS_AREA_BORDER_BOX: + bg_x = 0; + bg_y = 0; + bg_width = width; + bg_height = height; + break; + case GTK_CSS_AREA_PADDING_BOX: + default: + bg_x = border.left; + bg_y = border.top; + bg_width = width - border.left - border.left; + bg_height = height - border.top - border.bottom; + break; + case GTK_CSS_AREA_CONTENT_BOX: + bg_x = border.left + padding.left; + bg_y = border.top + padding.top; + bg_width = width - border.left - border.right - padding.left - padding.right; + bg_height = height - border.top - border.bottom - padding.top - padding.bottom; + break; + } + + context.width = bg_width; + context.height = bg_height; if (optional_background) pattern = cairo_pattern_reference (optional_background); @@ -1465,10 +1503,6 @@ render_background_internal (GtkThemingEngine *engine, "background-image", &pattern, NULL); - _gtk_theming_engine_get (engine, flags, &context, - "background-repeat", &repeat, - "box-shadow", &box_shadow, - NULL); cairo_save (cr); cairo_translate (cr, x, y); @@ -1656,8 +1690,6 @@ render_background_internal (GtkThemingEngine *engine, cairo_pattern_destroy (other_pattern); } - gtk_theming_engine_get_border (engine, flags, &border); - /* In the CSS box model, by default the background positioning area is * the padding-box, i.e. all the border-box minus the borders themselves, * which determines also its default size, see @@ -1666,12 +1698,28 @@ render_background_internal (GtkThemingEngine *engine, * In the future we might want to support different origins or clips, but * right now we just shrink to the default. */ - _gtk_rounded_box_init_rect (&border_box, 0, 0, width, height); - _gtk_rounded_box_apply_border_radius (&border_box, engine, flags, junction); - _gtk_rounded_box_shrink (&border_box, - border.top, border.right, - border.bottom, border.left); - _gtk_rounded_box_path (&border_box, cr); + _gtk_rounded_box_init_rect (&padding_box, 0, 0, width, height); + _gtk_rounded_box_apply_border_radius (&padding_box, engine, flags, junction); + clip_box = padding_box; + _gtk_rounded_box_shrink (&padding_box, + border.top, border.right, + border.bottom, border.left); + if (clip == GTK_CSS_AREA_PADDING_BOX) + { + _gtk_rounded_box_shrink (&clip_box, + border.top, border.right, + border.bottom, border.left); + } + else if (clip == GTK_CSS_AREA_CONTENT_BOX) + { + _gtk_rounded_box_shrink (&clip_box, + border.top + padding.top, + border.right + padding.right, + border.bottom + padding.bottom, + border.left + padding.left); + } + + _gtk_rounded_box_path (&clip_box, cr); if (pattern) { @@ -1694,13 +1742,15 @@ render_background_internal (GtkThemingEngine *engine, else { cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); - scale_width = width; - scale_height = height; + scale_width = bg_width; + scale_height = bg_height; } + cairo_translate (cr, bg_x, bg_y); cairo_scale (cr, scale_width, scale_height); cairo_set_source (cr, pattern); cairo_scale (cr, 1.0 / scale_width, 1.0 / scale_height); + cairo_translate (cr, -bg_x, -bg_y); } else gdk_cairo_set_source_rgba (cr, &bg_color); @@ -1715,7 +1765,7 @@ render_background_internal (GtkThemingEngine *engine, if (box_shadow != NULL) { - _gtk_box_shadow_render (box_shadow, cr, &border_box); + _gtk_box_shadow_render (box_shadow, cr, &padding_box); _gtk_shadow_unref (box_shadow); } -- 2.30.2